package org.dant.ant.extension.net.socket;

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;

import org.dant.ant.extension.net.NetConstants;
import org.dant.ant.extension.tasks.internal.Endpoint;
import org.dant.ant.extension.tasks.internal.RemoteCommand;
import org.dant.ant.extension.tasks.internal.RemoteResponse;
import org.dant.ant.extension.net.Dispatcher;
import org.dant.ant.extension.net.DefaultDispatcher;

public class SocketServer {

  protected Endpoint ep = new Endpoint();
  protected Dispatcher dispatcher = new DefaultDispatcher();
  protected ByteBuffer objBuffer = ByteBuffer.allocate(1024);
  
  public SocketServer() throws Exception {
    this(NetConstants.DEFAULT_SOCKET_PORT);
  }
  
  public SocketServer(int port) throws Exception {
    ep.setPort(port+"");
    ep.setProtocol(NetConstants.SOCKET_PROTOCOL);
    acceptConnections(port);
  }
  
  public static void main(String[] args) throws Exception {
    try {
    if (args.length < 1) {
      new SocketServer();
    } else {
      new SocketServer(Integer.parseInt(args[0]));
    }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  private String getFullURL() {
    return ep.getFullURL();
  }
  
  private void acceptConnections(int port) throws Exception {
    ServerSocket server_socket = new ServerSocket(port);
    System.out.println("Running on port " + getFullURL());
    
    while(true) {
      Socket socket = server_socket.accept();
      System.out.println("New connection accepted " + socket.getInetAddress() +":" + socket.getPort());
      ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
      ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

      RemoteCommand request = (RemoteCommand) input.readObject();
      
      RemoteResponse response = new RemoteResponse();
      response.setFullURL(getFullURL());
      dispatcher.dispatch(request, response);
      
      output.writeObject(response);
      output.flush();
      System.out.println("Response send out");
      
      try {
        socket.close();
        output.close();
        input.close();
        System.out.println("Connection closed by client");
      } catch (IOException e) {
        System.out.println(e);
      }
    }
  }
}
